package persistence.database;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import core.exception.SaveException;

import persistence.TransactionManager;

/**
 * TransactionManager for database persistence
 * @author Sabrina
 *
 */
public class DBTransactionManager implements TransactionManager {

	private Connection _connection;
	
	/**
	 * construct a DBTransactionManager
	 * @throws Exception 
	 */
	public DBTransactionManager() throws SaveException
	{
		try {
			Class.forName("org.sqlite.JDBC");
		} catch (ClassNotFoundException e) {
			throw new SaveException(e.getMessage());
		}
		File f = new File( "db" + File.separator + "tracker.sqlite");
		if (!f.exists()){
			createDatabase();
		}
	}
	
	/**
	 * @inheritDoc
	 */
	@Override
	public void beginTransaction() throws SaveException {
		String dbName = "db" + File.separator + "tracker.sqlite";
		String connectionURL = "jdbc:sqlite:" + dbName;
		
		assert (_connection == null);
		
		try {
			_connection = DriverManager.getConnection(connectionURL);
			_connection.setAutoCommit(false);
		} catch (SQLException e) {
			throw new SaveException(e.getMessage());
		}
		
			
	}

	/**
	 * Gets the connection based on type of data persistence
	 * @return the connection
	 * @throws Exception thrown if problem occurred getting the connection
	 */
	public Connection getConnection() throws SaveException {
		return _connection;
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void endTransaction(boolean commit) throws SaveException {
		assert (_connection != null);		
		
		try {
			if (commit) {
				_connection.commit();
			}
			else {
				_connection.rollback();
			}
			
		} catch (SQLException e) {
			throw new SaveException(e.getMessage());
		}
		finally {
			if (_connection != null)
				try {
					_connection.close();
				} catch (SQLException e) {
					throw new SaveException(e.getMessage());
				}
		}
		
		_connection = null;

	}
	
	private void createDatabase() throws SaveException{
		beginTransaction();
		try{
			BufferedReader reader = new BufferedReader(new FileReader("createdb.sql"));
	
			String line;
			do{
				line = reader.readLine();
				if (line != null){
					PreparedStatement stmt = _connection.prepareStatement(line);
					stmt.execute();
				}
				
			}while (line != null);
			
			reader.close();
		}
		catch(Exception e){
			throw new SaveException(e.getMessage());
		}
		
		endTransaction(true);
	}

}
